// Copyright DustedPixels.com 2008. All rights reserved.

package com.dustedpixels.asm.analysis;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.BasicInterpreter;
import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.Value;

import com.dustedpixels.asm.Types;


/**
 * @author micapolos@gmail.com (Michal Pociecha-Los)
 */
public final class ThisInterpreter extends InterpreterAdapter {
  public static final class Values {
    public static final Value THIS = new BasicValue(Types.ofObject());
    public static final Value MAYBE_THIS = new BasicValue(Types.ofObject());
  }
  
  public ThisInterpreter() {
    super(new BasicInterpreter());
  }
  
  @Override
  public Value copyOperation(AbstractInsnNode insn, Value value) throws AnalyzerException {
    if (insn.getOpcode() == Opcodes.ALOAD) {
      VarInsnNode varInsn = (VarInsnNode) insn;
      if (varInsn.var == 0) return Values.THIS;
    }
    return super.copyOperation(insn, value);
  }

  @Override
  public Value merge(Value v, Value w) {
    if (v == Values.THIS && w != Values.THIS) {
      return Values.MAYBE_THIS;
    } else if (v != Values.THIS && w == Values.THIS) {
      return Values.MAYBE_THIS;
    } else {
      return super.merge(v, w);
    }
  }
}
